<!DOCTYPE html>
<head>
    <title>时间轴安排</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <script src="./common.js"></script>
    <script src="./vue.min.js"></script>
    <link href="./lib/bootstrap.min.css" rel="stylesheet">
    <!-- <script src="./axios.min.js"></script> -->
    <style>
        [v-cloak]{
            display:none;
        }
        .desc{
            font-size:80%;
            color:#aaa;
        }
        div.skill-info{
            display:flex;
            
            height:36px;
        }
        .skill-info-show:first-child{
            flex:1;
        }
        .skill-info-show:last-child{
            flex:1;
        }
        .skill-info-show:first-child{
            border-right:1px solid #eee;
        }
        td.skill-info{
            padding:0 !important;
        }
        .skill-active{
            background-color: #80ff80;
        }
        .skill-invalid{
            background-color: #ffC0C0;
        }
        .skill-duration{
            background-color: #C0C0FF;
        }
        td{
            vertical-align: middle !important;
        }
        .del-btn{
            position:absolute;
            right:0;
            transform: scale(0.8);
        }
        .share-container{
            position:fixed;
            top:0;
            left:0;
            right:0;
            bottom:0;
            padding:5%;
            background-color:rgba(255,255,255,0.5);
            z-index:100;
        }
        .time-col{
            position:relative;
        }
    </style>
</head>
<body>
<div id="container" v-cloak style="padding:10px;">
    <div class="share-container" v-if="sharing">
        <button class="btn btn-success" @click="importData">导入</button>
        <button class="btn btn-default" @click="clearData">清空</button>
        <button class="btn btn-danger" @click="sharing=false">关闭</button>
        <textarea class="form-control" style="width:100%;height:90%;resize:none;margin-top: 10px;">{{sharingText}}</textarea>
    </div>
    <select class="form-control" style="width:260px;display:inline-block;" v-model="selectedDataIndex">
        <option v-for="data,i in savedDatas" :value="i">
            {{data.name}} (技能{{data.skills.length}} 事件{{data.timeline.length}})
        </option>
    </select>
    <input class="form-control" style="width:100px;display:inline-block;" v-model="newDataName" placeholder="新名称"> 
    <button class="btn btn-success" @click="dataSave">保存</button>
    <button class="btn btn-primary" @click="dataLoad">读取</button>
    <button class="btn btn-danger" @click="dataDelete">删除</button>
    <button class="btn btn-info" @click="dataShare">分享</button>
    <span style="margin-left:50px">
        技能冲突处理：
        <select class="form-control" style="width:260px;display:inline-block;" v-model="howToDoOnConflict">
            <option value="0">提醒</option>
            <option value="1">取消冲突技能</option>
            <option value="2">忽略本次设置</option>
        </select>
    </span>
    <span>时间轴安排高级版已发布：<a href="./timeline.html">点击进入</a></span>
    <table class="table table-striped table-hover table-bordered" style="margin-top:10px;">
        <tr>
            <td width="100px">时间</td>
            <td width="500px">事件</td>
            <td width="120px" v-for="skill,i in skills">
                <div style="position:relative;">
                    {{skill.name}} <button class="btn btn-xs btn-danger del-btn" @click="delSkill(skill,i)">X</button>
                    <div class="desc">
                        <template v-if="skill.duration">{{skill.duration}} /</template>
                        {{skill.cd}} 
                    </div>
                </div>
            </td>
            <td width="150px">
                <input title="技能名称" v-model="newSkill.name" class="form-control" placeholder="+ 新技能" @keydown.enter="enterNewSkill">
            </td>
            <td></td>
        </tr>
        <tr>
            <td colspan="2">
                <input class="form-control" @keydown.enter="enterLine($event)" placeholder="0:00 开始" v-model="inputText" @blur="inputErrMsg=''">
                <span v-if="inputErrMsg" style="color:red;">{{inputErrMsg}}</span>
            </td>
            <td v-for="skill in skills">
                <div class="skill-info">
                    <div>
                        <input title="持续时间" min="0" class="form-control" v-model="skill.duration">
                    </div>
                    <div>
                        <input title="冷却时间" min="0" class="form-control" v-model="skill.cd" @change="onSkillChange(skill)">
                    </div>
                </div>
            </td>
            <td>
                <div class="skill-info">
                    <div>
                        <input title="持续时间" min="0" class="form-control" v-model="newSkill.duration" placeholder="持续"  @keydown.enter="enterNewSkill">
                    </div>
                    <div>
                        <input title="冷却时间" min="0" class="form-control" v-model="newSkill.cd" placeholder="冷却"  @keydown.enter="enterNewSkill">
                    </div>
                </div>
            </td>
        </tr>
        <tr v-for="line,index in timeline">
            <td>
                <div class="time-col">
                    {{line.time | timeFormat}}
                    <button class="btn btn-xs btn-danger del-btn" @click="delLine(line,index)">X</button>
                </div>
            </td>
            <td @dblclick="modifyLineTitle(line)">
                {{line.title}}
            </td>
            <td v-for="skill in skills" class="skill-info">
                <div class="skill-info">
                    <div title="持续状态" class="skill-info-show"
                        :class="{
                            'skill-duration':line.actions[skill.name]&&line.actions[skill.name].duration>0
                        }">
                        &nbsp;
                    </div>
                    <div title="冷却状态" class="skill-info-show" 
                        :class="{
                            'skill-active':line.actions[skill.name]&&line.actions[skill.name].use,
                            'skill-invalid':line.actions[skill.name]&&!line.actions[skill.name].use&&line.actions[skill.name].cd>0
                        }" 
                        @click="useSkill(line,skill,index)">
                        &nbsp;
                    </div>
                </div>
            </td>
            <td></td>
        </tr>
        
    </table>
</div>
<script>
'use strict';

var defaultSkills=[
    {
        name:"铁壁", //名称
        cd:90, //冷却 秒
        duration:20, //持续
    },
    {
        name:"预警",
        cd:120,
        duration:10,
    },
    {
        name:"血仇",
        cd:60,
        duration:5,
    },
]


var timeline=[ 
    {
        time:0, //时间，毫秒
        type:"event",
        title:"开始", //标题
        actions:{  } //skills[0].name : { cd duration}
    }
];
function copy(data){
    return JSON.parse(JSON.stringify(data));
}
function save(alldata){
    localStorage.setItem("CCINO_SIMPLE_TIMELINE",JSON.stringify(alldata));
}
function load(){
    var data=localStorage.getItem("CCINO_SIMPLE_TIMELINE");
    if(data){
        try{
            data=JSON.parse(data);
        }catch(e){
            console.error(e);
            data=[];
        }
    }else{
        data=[];
    }
    return data;
}
var vueapp = new Vue({
    el: "#container",
    data: {
        sharing:false,
        sharingText:"",
        selectedDataIndex:0,
        newDataName:"",
        howToDoOnConflict:"0",
        savedDatas:load(),
        timeline:timeline,
        skills:defaultSkills,
        inputErrMsg:"",
        inputText:"",
        newSkill:{
            name:"",
            cd:null,
            duration:null,
        },
    },
    methods: {
        dataSave:function(){
            if(this.newDataName&&this.newDataName.length>0){
                var data=copy(this.getAllData());
                data.name=this.newDataName;
                var i=this.savedDatas.push(data);
                this.selectedDataIndex=this.savedDatas.length-1;
                this.newDataName="";
                save(this.savedDatas);
            }else{
                if(this.selectedDataIndex>=0&&this.selectedDataIndex<this.savedDatas.length){
                    var name=this.savedDatas[this.selectedDataIndex].name;
                    var data=copy(this.getAllData());
                    Vue.set(this.savedDatas,this.selectedDataIndex,data);
                    data.name=name;
                    save(this.savedDatas);
                }
            }
        },
        dataLoad:function(slince){
            if(this.selectedDataIndex>=0&&this.selectedDataIndex<this.savedDatas.length){
                var savedData=copy(this.savedDatas[this.selectedDataIndex]);
                this.timeline=savedData.timeline;
                this.skills=savedData.skills;
            }else{
                if(!slince)
                    alert("请选择一个存档");
            }
        },
        dataDelete:function(){
            if(this.selectedDataIndex>=0&&this.selectedDataIndex<this.savedDatas.length){
                var savedData=this.savedDatas[this.selectedDataIndex];
                if(confirm("是否确认删除该存档["+savedData.name+"] ?")){
                    this.savedDatas.splice(this.selectedDataIndex,1);
                    save(this.savedDatas);
                }
            }else{
                alert("请选择一个存档");
            }
        },
        dataShare:function(){
            this.sharing=true;
            if(this.selectedDataIndex>=0&&this.selectedDataIndex<this.savedDatas.length){
                var savedData=this.savedDatas[this.selectedDataIndex];
                this.sharingText=JSON.stringify(savedData,null,2);
            }
        },
        clearData:function(){
            this.sharingText="";
        },
        importData:function(){
            try{
                var data=JSON.parse(this.sharingText);
                this.savedDatas.push(data);
                this.sharing=false,
                alert("导入成功");
                save(this.savedDatas);
            }catch(e){
                alert("数据格式不正确");
            }
        },
        getAllData:function(){
            return {
                timeline:this.timeline,
                skills:this.skills
            }
        },
        delLine:function(line,index){
            this.timeline.splice(index,1);
        },
        delSkill:function(skill,i){
            if(confirm("是否删除该技能?")){
                this.skills.splice(i,1);
                for(var i=0;i<this.timeline.length;++i){
                    let line=this.timeline[i];
                    delete(line.actions[skill.name]);
                }
            }
        },
        enterNewSkill:function(){
            if(this.newSkill.name&&this.newSkill.name.length>0){
                for(var skill of this.skills){
                    if(skill.name==this.newSkill.name){
                        alert("技能名不可以重复")
                        return;
                    }
                }
                if(this.newSkill.cd==null) this.newSkill.cd=0;
                if(this.newSkill.duration==null) this.newSkill.duration=0;
                this.skills.push(JSON.parse(JSON.stringify(this.newSkill)));
                this.newSkill.name="";
            }
        },
        onSkillChange:function(skill){
            let needReuseLines=[];
            for(let i=0;i<this.timeline.length;++i){
                let line=this.timeline[i];
                let action=line.actions[skill.name];
                if(action&&action.use){
                    needReuseLines.push({
                        line:line,
                        index:i
                    });
                }
            }
            for(var j=0;j<2;++j){
                for(let i=0;i<needReuseLines.length;++i){
                    let reuseLine=needReuseLines[i];
                    this.useSkill(reuseLine.line,skill,reuseLine.index,true);
                }
            }
        },
        enterLine:function(e){
            if(this.insertLine(this.inputText)){
                this.inputText="";
                this.inputErrMsg="";
            }else{
                this.inputErrMsg="格式错误";
            }
        },
        insertLine:function(lineStr){
            let reg=/^\s*(\d+)[:：](\d{1,2})([.:：](\d+))?\s+(.*)/.exec(lineStr);
            if(reg){
                let min=+reg[1];
                let sec=+reg[2];
                let millis=+reg[4];
                let info=reg[5];
                if(isNaN(min)) min=0;
                if(isNaN(sec)) min=0;
                if(isNaN(millis)) millis=0;
                let time=millis+sec*1000+min*60*1000;
                if(info) info=info.trim();
                let i;
                for(i=0;i<this.timeline.length;++i){
                    let line=this.timeline[i];
                    if(line.time>time){
                        break;
                    }
                }
                //计算actions
                let actions={};
                if(i>=1){ //从上一条计算
                    let prevLine=this.timeline[i-1];
                    if(prevLine){ 
                        let dt=time-prevLine.time;
                        for(var prop in prevLine.actions){
                            var action=prevLine.actions[prop];
                            var cd=action.cd-time;
                            var duration=action.duration-time;
                            if(cd>0||duration>0){
                                actions[prop]={
                                    cd:cd>0?cd:0,
                                    duration:duration>0?duration:0
                                };
                            }
                        }
                    }
                }
                //--设置
                this.timeline.splice(i,0,{
                    time:time,
                    type:"event",
                    title:info,
                    actions:actions
                });
                return true;
            }else{
                return false;
            }
        },
        useSkill:function(line,skill,index,slince){
            let thisAction=line.actions[skill.name];
            if(thisAction){
                if(!thisAction.use&&thisAction.cd>0){
                    return; //未到CD
                }
            }
            var cdTime=line.time+skill.cd*1000;
            for(var i=index+1;i<this.timeline.length&&this.timeline[i].time<cdTime;++i){
                var action=this.timeline[i].actions[skill.name];
                if(action&&action.use){
                    if(this.howToDoOnConflict=="0"){ //提醒
                        if(slince||confirm("与后面技能冲突，是否取消后续冲突技能的施放？")){
                            this.useSkill(this.timeline[i],skill,i);
                        }else{
                            return;
                        }
                    }else if(this.howToDoOnConflict=="1"){ //取消冲突
                        this.useSkill(this.timeline[i],skill,i);
                    }else{
                        return;
                    }
                }
            }
            let cancel=thisAction&&thisAction.use;
            if(cancel){ //取消
                Vue.set(line.actions,skill.name,undefined);
            }else{ //使用
                Vue.set(line.actions,skill.name,{
                    use:true,
                    cd:skill.cd*1000,
                    duration:skill.duration*1000
                });
            }
            //---- 循环修改
            let cd=skill.cd*1000;
            let duration=skill.duration*1000;
            let thisLine=line;
            while(++index<this.timeline.length){
                let nextLine=this.timeline[index];
                let nextAction=nextLine.actions[skill.name];
                if(nextAction&&nextAction.use){
                    break;
                }
                if(cancel){ //取消
                    if(nextAction&&!nextAction.use){
                        Vue.set(nextLine.actions,skill.name,undefined);
                    }
                }else{ //使用
                    var dt=nextLine.time-thisLine.time;
                    cd-=dt;
                    duration-=dt;
                    if(cd>0||duration>0){
                        Vue.set(nextLine.actions,skill.name,{
                            cd:cd>0?cd:0,duration:duration>0?duration:0
                        })
                    }
                }
                thisLine=nextLine;
            }
        },
        modifyLineTitle:function(line){
            let title=prompt("请输入要设置的内容",line.title);
            if(title){
                line.title=title;
            }
        }
    },
    filters:{
        timeFormat:function(time){
            let d=new Date(time);
            return d.format("mm:ss.fff");
        }
    }
});
vueapp.dataLoad(true);

</script>
</body>